from django.http import HttpResponse, JsonResponse
from rest_framework import status
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings

# def my_jwt_response_payload_handler(token, user=None, request=None): # 返回什么，前端就能看到什么样子
#     return {
#         'token': token,
#         'msg':'登录成功',
#         'code':0,
#         'username':user.username

#     }

"""改动token认证"""
from rest_framework.authentication import BaseAuthentication  # 基于它
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication # 基于它
from rest_framework.exceptions import AuthenticationFailed
# from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.utils import jwt_decode_handler # 跟上面是一个
import jwt
from rest_framework_jwt.views import JSONWebTokenAPIView, ObtainJSONWebToken, RefreshJSONWebToken, VerifyJSONWebToken
from datetime import datetime

class MyJSONWebTokenAPIView(JSONWebTokenAPIView):
    
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            print(serializer)
            user = serializer.object.get('user') or request.user
            token = serializer.object.get('token')
            response_data = jwt_response_payload_handler(token, user, request)
            response = Response(response_data)
            if api_settings.JWT_AUTH_COOKIE:
                expiration = (datetime.utcnow() +
                              api_settings.JWT_EXPIRATION_DELTA)
                response.set_cookie(api_settings.JWT_AUTH_COOKIE,
                                    token,
                                    expires=expiration,
                                    httponly=True)
            return response
        error_data = jwt_response_payload_error_handler(serializer, request)
        return Response(error_data, status=status.HTTP_200_OK)

def jwt_response_payload_handler(token, user=None, request=None):
    # 自定义返回 JWT
    return  {
        "msg": "success",
        "code": 200,
        "data": [{
        	# data自定义你接口想返回的信息
            'token': token,
            'username': user.username
        }]
    }

  

def jwt_response_payload_error_handler(serializer, request=None):

    return {
        "msg": "用户名或者密码错误",
        "code": 9992,
        "detail": serializer.errors
    }

      
      
      

class MyObtainJSONWebToken(ObtainJSONWebToken, MyJSONWebTokenAPIView):
    pass


class MyRefreshJSONWebToken(RefreshJSONWebToken, MyJSONWebTokenAPIView):
    pass


class MyVerifyJSONWebToken(VerifyJSONWebToken, MyJSONWebTokenAPIView):
    pass




obtain_jwt_token = MyObtainJSONWebToken.as_view()
refresh_jwt_token = MyRefreshJSONWebToken.as_view()
verify_jwt_token = MyVerifyJSONWebToken.as_view()
# from users import models
# class MyJwtAuthentication(BaseAuthentication):
#     def authenticate(self, request):
#         jwt_value=request.META.get('HTTP_AUTHORIZATION')
#         if jwt_value:
#             try:
#             #jwt提供了通过三段token，取出payload的方法，并且有校验功能
#                 payload=jwt_decode_handler(jwt_value)
#             except jwt.ExpiredSignature:
#                 raise AuthenticationFailed('签名过期')
#             except jwt.InvalidTokenError:
#                 raise AuthenticationFailed('用户非法')
#             except Exception as e:
#                 # 所有异常都会走到这
#                 raise AuthenticationFailed(str(e))
#             # 因为payload就是用户信息的字典
#             print(payload)
#             # return payload, jwt_value
#             # 需要得到user对象，
#             # 第一种，去数据库查
#             # user=models.User.objects.get(pk=payload.get('user_id'))
#             # 第二种不查库
#             user=models.User(id=payload.get('user_id'),username=payload.get('username'))
#             return user,jwt_value
#         # 没有值，直接抛异常
#         raise AuthenticationFailed('您没有携带认证信息')



class MyJwtAuthentication(BaseJSONWebTokenAuthentication):
    def authenticate(self, request):
        ret = {"code": 10000}
        jwt_value=request.META.get('HTTP_AUTHORIZATION')
        print(jwt_value)
        if jwt_value:
            try:
            #jwt提供了通过三段token，取出payload的方法，并且有校验功能
                payload=jwt_decode_handler(jwt_value)
            except jwt.ExpiredSignature:
                raise AuthenticationFailed('签名过期')
            except jwt.InvalidTokenError:
                raise AuthenticationFailed('用户非法')
            except Exception as e:
                # 所有异常都会走到这
                raise AuthenticationFailed(str(e))
                # HttpResponse(ret)
            user=self.authenticate_credentials(payload)
            return user,jwt_value
        # 没有值，直接抛异常
        raise AuthenticationFailed('您没有携带认证信息')


"""手机号登陆设置 """
from django.contrib.auth.backends import ModelBackend
import re
from .models import User
from django.db.models import Q

class CustomBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            # 先按用户名查找
            user = User.objects.get(
                Q(username=username) |  Q(mobile=username) | Q(email=username)
            )
        except User.DoesNotExist as e:
            return None
        # 如果用户存在再校验密码
        if user.check_password(password):
            return user


# apps/utils/yunpian.py

import requests
import json

class YunPian(object):

    def __init__(self, api_key):
        self.api_key = api_key
        self.single_send_url = "https://sms.yunpian.com/v2/sms/single_send.json"

    def send_sms(self, code, mobile):
        #需要传递的参数
        parmas = {
            "apikey": self.api_key,
            "mobile": mobile,
            "text": "【邓志雄】您的验证码是{code}。如非本人操作，请忽略本短信".format(code=code)
        }

        response = requests.post(self.single_send_url, data=parmas)
        re_dict = json.loads(response.text)
        return re_dict

if __name__ == "__main__":
    #例如：9b11127a9701975c734b8aee81ee3526
    yun_pian = YunPian("2e87d17327d4be01608f7c6da23ecea2")
    yun_pian.send_sms("2018", "手机号码")